//
// Created by Tony on 2024/5/26.
//

#ifndef COMPILER_SYMBOL_FINDER_H
#define COMPILER_SYMBOL_FINDER_H

#include "../tvm/rt_code/ClassTable.h"
#include "SymbolTable.h"
#include "Visitor.h"
#include <cstdint>

namespace Compiler {

class SymbolFinder final : public Visitor {
    // params
    shared_ptr<RtCode::ClassTable> mClassTable;
    shared_ptr<RtCode::Class> mClass;
    shared_ptr<SymbolTable> mClassSymbolTable;
    shared_ptr<SymbolTable> mCurrentSymbolTable;

    // status
    shared_ptr<SymbolTable> mImportSymbolTable;

public:
    explicit SymbolFinder(const shared_ptr<RtCode::ClassTable>& classTable)
        : mClassTable(classTable) {}

    SymbolFinder(const shared_ptr<RtCode::Class>& clazz,
                 const shared_ptr<RtCode::ClassTable>& classTable,
                 const shared_ptr<SymbolTable>& classSymbolTable,
                 const shared_ptr<SymbolTable>& currentSymbolTable)
        : mClassTable(classTable), mClass(clazz), mClassSymbolTable(classSymbolTable),
          mCurrentSymbolTable(currentSymbolTable) {}

    // abstract ast
    int32_t visit(Parser::Ast* ast) override;

    // Literal
    int32_t visit(Parser::BooleanLiteral* ast) override;
    int32_t visit(Parser::CharLiteral* ast) override;
    int32_t visit(Parser::Flt64Literal* ast) override;
    int32_t visit(Parser::Int64Literal* ast) override;
    int32_t visit(Parser::NullLiteral* ast) override;
    int32_t visit(Parser::StringLiteral* ast) override;

    // Name
    int32_t visit(Parser::Name* ast) override;

    // OP
    int32_t visit(Parser::Operator* ast) override;

    // Expr
    int32_t visit(Parser::BinaryExpr* ast) override;
    int32_t visit(Parser::TernaryExpr* ast) override;
    int32_t visit(Parser::UnaryExpr* ast) override;

    // Type Tag
    int32_t visit(Parser::TypeTag* ast) override;
    int32_t visit(Parser::AccessFlags* ast) override;

    // Statement
    int32_t visit(Parser::SimpleStmt* ast) override;
    int32_t visit(Parser::AssertStmt* ast) override;
    int32_t visit(Parser::BlockStmt* ast) override;
    int32_t visit(Parser::ForStmt* ast) override;
    int32_t visit(Parser::IfStmt* ast) override;
    int32_t visit(Parser::NullStmt* ast) override;
    int32_t visit(Parser::VarDefStmt* ast) override;
    int32_t visit(Parser::ReturnStmt* ast) override;

    // array
    int32_t visit(Parser::ArrayIndex* ast) override;

    // function
    int32_t visit(Parser::ParameterList* ast) override;
    int32_t visit(Parser::FunctionDefine* ast) override;
    int32_t visit(Parser::ArgumentList* ast) override;

    // module
    int32_t visit(Parser::Module* ast) override;

    // class
    int32_t visit(Parser::FieldDefine* ast) override;
    int32_t visit(Parser::MethodDefine* ast) override;
    int32_t visit(Parser::NativeMethodDecl* ast) override;
    int32_t visit(Parser::ClassBody* ast) override;
    int32_t visit(Parser::ClassDefine* ast) override;
    int32_t visit(Parser::ClassModule* ast) override;

    // view
    int32_t visit(Parser::ViewBuilder* ast) override;
    int32_t visit(Parser::ViewBuilderList* ast) override;
    int32_t visit(Parser::ViewBuilderBlock* ast) override;
    int32_t visit(Parser::AttributeSetter* ast) override;
    int32_t visit(Parser::AttributeSetterList* ast) override;
};

} // namespace Compiler

#endif // COMPILER_SYMBOL_FINDER_H
